package com.telit.communicate.communicate;

import com.telit.communicate.constant.MsgSource;
import com.telit.communicate.constant.SystemName;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;


/**
 * @author zhouyu
 * @description 消息实例缓存
 */
public class MsgInstanceCache {


    /**
     * 消息来源总个数
     */
    private final static int TOTAL_SOURCE = MsgSource.class.getFields().length;

    /**
     * 分发系统总个数
     */
    private final static int TOTAL_SYSTEM = SystemName.class.getFields().length;

    /**
     * 消息缓存集合
     */
    private static final ConcurrentHashMap<String, List<BlockingQueue<Object>>> MSG_COLLECTION = new ConcurrentHashMap<>(TOTAL_SOURCE);


    /**
     * 创建容器
     */
    public static void createInstanceCache() {
        Field[] sourceFields = MsgSource.getFields();
        for (Field sourceField : sourceFields) {
            //待分发系统消息集合
            List<BlockingQueue<Object>> systemMsgCollection = new ArrayList<>(TOTAL_SOURCE);
            int length = SystemName.getFields().length;
            for (int i = 0; i < length; i++) {
                //消息集合
                BlockingQueue<Object> msgInfoCollection = new LinkedBlockingQueue<>(Integer.MAX_VALUE);
                systemMsgCollection.add(msgInfoCollection);
            }

            MSG_COLLECTION.put(sourceField.getName(), systemMsgCollection);
        }
    }


    /**
     * 根据消息来源,待分发系统获取消息集合
     *
     * @param msgSource  消息来源
     * @param systemName 待分发系统
     * @return 值
     */
    public static BlockingQueue<Object> getMsgInfoQueue(MsgSource msgSource, SystemName systemName) {
        return MSG_COLLECTION.get(msgSource.toString()).get(Math.abs(systemName.toString().hashCode()) % TOTAL_SYSTEM);
    }

    /**
     * 添加键值对到容器
     *
     * @param msgSource  消息来源
     * @param systemName 系统名称
     * @param object     消息实体
     */
    public static void setMsgInfo(MsgSource msgSource, SystemName systemName, Object object) throws InterruptedException {
        if (systemName!=null) {
            MSG_COLLECTION.get(msgSource.toString()).get(Math.abs(systemName.toString().hashCode()) % TOTAL_SYSTEM).put(object);
        }
    }

}
